#include "stdafx.h"
#include "CppUnitTest.h"
#include "../Geometry//Point.h"
#include "../Geometry//Triangle.h"
#include "../Geometry//Vector.h"
#include "../Geometry//Flatness.h"
#include <functional>

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace GeometryTests
{		
	TEST_CLASS(PointTest)
	{
	public:
		
		TEST_METHOD(PShouldConstructWithoutParametres)
		{
			// TODO: Your test code here
			Point<int> A;
			Assert::AreEqual(A.m_x,0);
			Assert::AreEqual(A.m_y,0);
			Assert::AreEqual(A.m_z,0);
		}

		TEST_METHOD(PShouldConstructWithParametres)
		{
			// TODO: Your test code here
			Point<int> A(3,4,5);
			Assert::AreEqual(A.m_x,3);
			Assert::AreEqual(A.m_y,4);
			Assert::AreEqual(A.m_z,5);
			
			Point<double> B(3.3,4,5);
			Assert::AreEqual(B.m_x,3.3);
			Assert::AreEqual(B.m_y,4.0);
			Assert::AreEqual(B.m_z,5.0);
		}

		TEST_METHOD(PShouldUseOperatorEqual)
		{
			// TODO: Your test code here
			Point<int> A(3,4,5);
			Point<int> B=A;
			Assert::AreEqual(A.m_x,B.m_x);
			Assert::AreEqual(A.m_y,B.m_y);
			Assert::AreEqual(A.m_z,B.m_z);
		}
	};

	TEST_CLASS(VectorTest)
	{
	public:
		
		TEST_METHOD(VShouldConstructWithoutParametres)
		{
			// TODO: Your test code here
			Vector<int> v1;
			Assert::AreEqual(v1.m_x,0);
			Assert::AreEqual(v1.m_y,0);
			Assert::AreEqual(v1.m_z,0);
		}
		
		TEST_METHOD(VShouldConstructWithParametres)
		{
			// TODO: Your test code here
			Point<int> A(1,1,1);
			Point<int> B(3,3,3);
			Vector<int> v1(A,B);
			Assert::AreEqual(v1.m_x,2);
			Assert::AreEqual(v1.m_y,2);
			Assert::AreEqual(v1.m_z,2);
		}

		TEST_METHOD(VShouldUseOperatorVecPr)
		{
			// TODO: Your test code here
			Vector<int> v1(1,0,0);
			Vector<int> v2(0,1,0);
			Vector<int> res=v1^v2;
			Assert::AreEqual(res.m_x,0);
			Assert::AreEqual(res.m_y,0);
			Assert::AreEqual(res.m_z,1);
		}

		TEST_METHOD(VLenghtSholdBeCorrect)
		{
			// TODO: Your test code here
			Vector<int> v1(1,1,1);
			Vector<int> v2(0,0,0);
			Vector<int> v3(0,0,1);
			Vector<int> v4(0,0,-1);
			Assert::AreEqual(v1.length(),sqrt(3));
			Assert::AreEqual(v2.length(),0.0);
			Assert::AreEqual(v3.length(),1.0);
			Assert::AreEqual(v4.length(),1.0);
		}
	
		TEST_METHOD(VShouldUseOperatorPro)
		{
			// TODO: Your test code here
			Vector<int> v1(0,0,1);
			Vector<int> v2(0,0,-1);
			Assert::AreEqual(v1*(-v2),1);
		}
	};

	TEST_CLASS(FlatnessTest)
	{
	public:
		
		TEST_METHOD(FShouldFindPointDeviation)
		{
			Point<int>A (0,0,1);
			Point<int>B (1,0,1);
			Point<int>C (0,1,1);
			Flatness<int> first(A,B,C);
			Point<int> our (0,0,0);
			double k=first.PointDeviation(our);
			Assert::AreEqual(k,-1.0);
			Point<int> our2 (1,1,1);
			k=first.PointDeviation(our2);
			Assert::AreEqual(k,0.0);
		}
		
	};

	TEST_CLASS(TriangleTest)
	{
	public:
		
		TEST_METHOD(TShouldEstimateIfPointInside)
		{
			Point<int>A (0,0,0);
			Point<int>B (2,0,0);
			Point<int>C (0,2,0);
			Triangle<int> triangle(A,B,C);
			Point<int>our1(1,1,0);
			bool flag=triangle.IfPointInside(our1);
			Assert::IsTrue(flag);
			Point<int>our2(1,1,1);
			flag=triangle.IfPointInside(our2);
			Assert::IsFalse(flag);
			Point<int>our3(1,0,0);
			flag=triangle.IfPointInside(our3);
			Assert::IsTrue(flag);
		}

		TEST_METHOD(TShouldEstimateIfIntersectOther)
		{
			Point<int>A1 (0,0,0);
			Point<int>B1 (2,0,0);
			Point<int>C1 (0,2,0);
			Point<int>A2 (2,0,0);
			Point<int>B2 (2,0,10);
			Point<int>C2 (3,0,11);
			Point<int>A3 (3,0,0);
			Point<int>B3 (2,0,10);
			Point<int>C3 (3,0,11);
			Triangle<int> triangle1 (A1,B1,C1);
			Triangle<int> triangle2 (A2,B2,C2);
			Triangle<int> triangle3 (A3,B3,C3);
			bool flag=triangle1.IfIntersectOther(triangle2);
			Assert::IsTrue(flag);
			flag=triangle1.IfIntersectOther(triangle3);
			Assert::IsTrue(flag);
		}
		
	};
}